/*Name: vigenere.cpp
  Last Modification: 31/05/10 16:25
  Description: fichier implémentant les fonctions nécessaire à l'algorithme
  License: GNU GPL v3
    Copyright (C) 2012 G. Bonnoron, P.Brunet, C. Duchene et F. Cornevaux-Juignet

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.*/

//inclusion du Header
#include "vigenere.h"

//Définition du constructeur
Vigenere::Vigenere() : Algorithme()
{
    clef="blabla";
    cle = new QLineEdit(QString::fromUtf8("Entrez votre clé ici"));
    crypter = new QTextEdit(QString::fromUtf8("Vos données (dé)chiffrées apparaîtront ici"));
}

//fonction modifiant un QChar "lettre" en le décalant de "decale" ou de "-decale" en fonction du boolean "dechif"
QChar Vigenere::changeLettre(QChar lettre,QChar decale, bool dechif)
{
    if(lettre == '\n'){
        return '\n';
    }
    else{
        int sortie = 0;
        if(dechif){
            sortie = lettre.toAscii()-decale.toAscii();
        }
        else{
            sortie = lettre.toAscii()-32+decale.toAscii()-32;
        }
        while(sortie <= 0)
            sortie += (127-32);
        return QChar(sortie%(127-32)+32);
    }
}

//fonction chiffrant les données entrées par l'utilisateur. Le paramètre permet d'indiquer si les données sont entrées
// à la main ou si c'est un fichier qui est utilisé.
void Vigenere::chiffre(bool fich)
{
    QTime mesure;   //Variable permettant de calculer le temps de chiffrement
    clef=cle->text();   //Pour prendre en compte la nouvelle clef
    mesure.start();
    if(fich){
        lineOut.clear();    //On vide le QByteArray de sortie
        for (int i = 0; i<line.length();i++){
        //On écrit dans le fichier la lettre décalée de la valeur ascii du caractère de la clef en cours
            lineOut.append(line[i]+clef[i%clef.length()].toAscii());
        }
    }
    else{
        messageOut = "";    //On vide la sortie
        for (int i = 0; i<messageIn.length();i++){
            //On change lettre par lettre le texte à chiffrer en prenant les caractères de la clef de façon périodique
            messageOut+=changeLettre(messageIn[i],clef[i%clef.length()],false);
        }
    }
    this->outVigenere(fich);// On affiche le résultat du chiffrement
    temps = mesure.elapsed();
}

//sur le même mode de fonctionnement que la fonction chiffre, celle-ci déchiffre les données entrées par
// l'utilisateur
void Vigenere::dechiffre(bool fich)
{
    QTime mesure;
    clef=cle->text();
    mesure.start();
    if(fich){
        lineOut.clear();
        for (int i = 0; i<line.length();i++){
            lineOut.append(line[i]-clef[i%clef.length()].toAscii()%256);
        }
    }
    else{
        messageOut = "";
        for (int i = 0; i<messageIn.length();i++){
            messageOut+=changeLettre(messageIn[i],clef[i%clef.length()],true);
        }
    }
    this->outVigenere(fich);
    temps = mesure.elapsed();
}

//fonction permettant de sortir le résultat du chiffrement ou du déchiffrement en fonction du type de données en entrée
void Vigenere::outVigenere(bool fichier)
{
    if(fichier){ //Si le type d'entrée est un fichier
        if(fileOut.isEmpty()) // On utilise le nom de fichier entré par l'utilisateur s'il existe
            fileOut = "out_Vigenere.txt";
        QFile file(fileOut);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
            crypter->setText(QString("Erreur lors du l'ecriture fichier"));
        else{
            file.write(lineOut);
            // on informe l'utilisateur du fichier d'écriture et de la fin d'exécution du programme
            crypter->setText(QString("sortie dans " + fileOut));
        }
    }
    else{
        crypter->setText(messageOut); //Si l'entrée s'est faite dans le programme, on ressort de la même façon
    }
}

//fonction permettant l'affiche de l'algorithme dans la partie droite de la plateforme
QList<QWidget *> Vigenere::affiche()
{
    QList<QWidget* > liste = QList<QWidget *>();
    QLabel* texte = new QLabel(QString::fromUtf8("<h1> Chiffre de Vigenère :</h1>"));
    liste.append(texte);
    liste.append(cle);
    liste.append(crypter);
    return liste;
}

//fonction permettant d'avoir une aide pour cet algorithme. On a donc son fonctionnement et son utilisation
QString Vigenere::aide()
{
    QString sortie;
    sortie.append(QString::fromUtf8("<h1>Chiffre de Vigenère</h1>"));
    sortie.append(QString::fromUtf8("<h2>Le principe</h2><div align = 'justify'> Tout comme le code César, cet algorithme est à clé symétrique et repose sur le principe de substitution. "));
    sortie.append(QString::fromUtf8("Cependant, contrairement à la méthode précédente, le décalage n'est pas le même selon la place de la lettre dans le texte clair. En effet, le principe est, grâce à une clef de plusieurs caractères, d'effectuer des décalages différents sur les lettres du texte clair pour les chiffrer. "));
    sortie.append(QString::fromUtf8("Il a été inventé par le diplomate français Blaise de Vigenère durant la deuxième partie du XVIème siècle. "));
    sortie.append(QString::fromUtf8("Il s'agit d'utiliser la méthode de César par colonne, les colonnes étant définies en fonction de la clé. Sur l'exemple ci-après, le texte est réparti sur sept colonnes.</div> "));
    sortie.append(QString::fromUtf8("<table><tr><td>E</td><td>X</td><td>E</td><td>M</td><td>P</td><td>L</td><td>E</tr><tr><td>T</td><td>E</td><td>X</td><td>T</td><td>E</td><td>D</td><td>E</tr><tr><td>D</td><td>E</td><td>M</td><td>O</td><td>N</td><td>S</td><td>T</tr><tr><td>R</td><td>A</td><td>T</td><td>I</td><td>O</td><td>N</td><td>!</tr></table> <div align = 'justify'>"));
    sortie.append(QString::fromUtf8("La première ligne est la clé. Le texte est ensuite codé par colonne. Les première, troisième et septième colonnes verront leurs lettres se décaler de cinq rangs dans l'alphabet, tandis que celle de la deuxième colonne seront décalées de vingt-quatre rangs. "));
    sortie.append(QString::fromUtf8("Au final, le texte encodé est : <strong>YCCGU PJ ICRBDEYWYYVEZ !</strong> "));
    sortie.append(QString::fromUtf8("On remarque que la lettre  E est tantôt codée C ou U. Cette méthode a longtemps été réputée inviolable puisque une analyse de fréquences était très difficile. Elle a cependant été mise à mal trois siècles plus tard, au XIXème, par Charles Babbage. </div>"));
    sortie.append(QString::fromUtf8("<h2>L'utiliser dans le cadre de la plate-forme</h2>Vous pouvez entrer une clé dans le champ prévu. Cette clé peut être une chaine de caractères quelconque. "));
    return sortie;
}

//fonction permettant de connaitre le nom de l'algorithme
QString Vigenere::nom()
{
    return "Vigenere";
}

//Destructeur de Vigenere
Vigenere::~Vigenere()
{
}

//fonction permettant l'export de l'algorithme en bibliothèque dynamique
extern "C" MY_EXPORT Algorithme* maker()
{
    return new Vigenere();
}
